#include <stdio.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<string.h>
#include "../ddxc.h"
#include "lcd.h"
#define SEVER_BUF_SIZE 64
#define NAME_SIZE 64
#define NO -1

#define NO_WRITE -1
#define INT_SIZE 4
#define SHORT_SIZE 2
#define LONG_SIZE 8
#define CHAR_SIZE 1
#define STRING_TYPE 5
#define INT_TYPE 4
#define SHORT_TYPE 2
#define LONG_TYPE 8
#define CHAR_TYPE 1


typedef struct msg{
    char buf[SEVER_BUF_SIZE];
    int offset;
    int blocksize;
    long filesize;
    char type;
}msg,*msglist;

void my_close(int sockfd,int clientfd){

    if(sockfd > 0){
        close(sockfd);
    }
    if(clientfd > 0){
        close(clientfd);
    }

    return;
}

// int find_name(char* name){
//     for(int i=0;i<SEVER_BUF_SIZE;i++){
//         if(name[i] == '\0'){
//             return 0;
//         }
//     }
//     return -1;
// }

int putmsg(int clientfd,msglist node,int fd_r){
    int temp=0;
    memset(node->buf,0,SEVER_BUF_SIZE);
    temp =read(fd_r,(node->buf+INT_SIZE),node->blocksize-INT_SIZE);//读取数据
    if(temp == 0){
        printf("send complete\n");
        
        sleep(2);//等待客户端关闭
        return 0;
    }else if(temp > 0){
        sticky_packs_send_func(clientfd,node->buf,STRING_TYPE,temp);
    }else{
        return -1;
    }
    return 1;
}

int msg2_file(int sockfd,int clientfd,msglist node,char* name){
    if(sticky_packs_recv_func(clientfd,node->buf,STRING_TYPE) == -1){
        return -1;
    }

    
    node->filesize=file_size((node->buf+INT_SIZE));//获取文件大小并存入结构体中
    if(node->filesize <= 0){
        return -1;
    }
    strcpy(name,(node->buf+INT_SIZE));
    printf("%s\n",name);
    sticky_packs_send_func(clientfd,&node->filesize,INT_TYPE,node->filesize);
    
    return 0;
}

int msg4_send(int sockfd,int clientfd,msglist node,char* name){

    if(sticky_packs_recv_func(clientfd,&node->blocksize,INT_TYPE) == -1){
        return -1;
    }
    if(node->blocksize > SEVER_BUF_SIZE){
        node->blocksize = SEVER_BUF_SIZE;
    }
    if(sticky_packs_recv_func(clientfd,&node->offset,INT_TYPE) == -1){
        return -1;
    }
    printf("blocksize:%d,offset:%d\n",node->blocksize,node->offset);
    unserializa_msg(&node->filesize);
    if(node->offset >= node->filesize){
        return 0;
    }
    if(node->offset == ntohl(node->filesize)){
        return 0;
    }
    int fd_r = open(name,O_RDONLY);
    if(fd_r == -1){
        perror("open err");
        return -1;
    }
    printf("offset:%d\n",node->offset);
    lseek(fd_r,node->offset,SEEK_SET);//跳到偏移量所在位置
    while(1){
        int temp=putmsg(clientfd,node,fd_r);//发送消息
        if(temp == -1){
            close(fd_r);
            return -1;
        }else if(temp == 0){//正常关闭
            close(fd_r);
            return 0;
        }
    }
    close(fd_r);

}

int sever_creat(int* sockfd,int* clientfd){
    *sockfd = socket(AF_INET,SOCK_STREAM,0);//ipv4,tcp
    if(*sockfd == -1){
        perror("sock err");
        return -1;
    }
    //服务器地址:IP 端口号
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port =htons(8888);
    
    addr.sin_addr.s_addr=INADDR_ANY;//本地的ip都可以
    printf("IP=%s\n",inet_ntoa(addr.sin_addr));
    socklen_t addrlen= sizeof(addr);
    //绑定
    if(bind(*sockfd,(struct sockaddr*)&addr,addrlen) == -1){
        perror("bind err");
        my_close(*sockfd,NO);
        return -1;
    }

    //监听
    if(listen(*sockfd,5) == -1){
        perror("listen err");
        my_close(*sockfd,NO);
        return -1;
    }
    printf("waiting client connect!\n");

    //响应连接
    struct sockaddr_in client_addr;
    socklen_t clientlen;
    *clientfd=accept(*sockfd,NULL,NULL);
    if(*clientfd < 0){
        perror("accept err");
        my_close(*sockfd,NO);
        return -1;
    }
    printf("new connect comming\n");

    return 0;
}



int main(void){
    int sockfd;
    int clientfd;
    sever_creat(&sockfd,&clientfd);
    //收发数据
    // msg node;
    // int nodesize=sizeof(node);
    // memset(&node,0,nodesize);
    char name[NAME_SIZE]={};
    int pet_type=0;
    int x=0,y=0;
    print(0, 0, "./login.bmp");
    while(1){
        get_xy(&x,&y);
        pet_type = keybord(&x,&y);
        printf("%d\n",pet_type);
        name[INT_SIZE]=pet_type;
        if(sticky_packs_send_func(clientfd,name,STRING_TYPE,1) < 0){
            break;
        }else{
            printf("send success!\n");
        }
        if(pet_type > 100){
            sleep(3);
            break;
        }

    }
    //关闭
    my_close(sockfd,clientfd);


    return 0;
}
